package com.libui.navigatonbar

import com.libbase.MapCodable
import com.libbase.Weak
import com.libbase.cast
import com.libui.webview.WebViewEx
import java.util.*

typealias OnMenuTap = (menuData: MenuData?) -> Unit

class MenuData(
    val id: String = UUID.randomUUID().toString(),
    val icon: String? = null,
    val title: String? = null,
    val enabled: Boolean = true,
    val url: String? = null,
    var onTap: String? = null,
    val children: List<MenuData>? = null,
    val style: StyleData? = null,
    webView: WebViewEx? = null,
) : MapCodable {
    companion object {
        fun create(map: Map<String, Any>, webView: WebViewEx? = null): MenuData {
            val id: String = map["id"] as? String ?: UUID.randomUUID().toString()
            val children: List<MenuData>? =
                cast<List<Map<String, Any>>>(map["children"])?.let { childrenList ->
                    childrenList.map { create(it, webView) }
                }
            val enabled = map["enabled"] as? Boolean ?: true
            val style: StyleData? =
                cast<Map<String, Any>>(map["style"])?.let { StyleData.create(it) }

            return MenuData(
                id,
                map["icon"] as? String,
                map["title"] as? String,
                enabled,
                map["url"] as? String,
                map["onTap"] as? String,
                children,
                style,
                webView
            )
        }
    }

    var webView: WebViewEx? by Weak { webView }

    override fun toMap(): Map<String, Any> {
        val map = mutableMapOf<String, Any>(
            "id" to id, "enabled" to enabled
        )

        icon?.let {
            map["icon"] = it
        }

        title?.let {
            map["title"] = it
        }

        url?.let {
            map["url"] = it
        }

        onTap?.let {
            map["onTap"] = it
        }

        children?.let {
            map["children"] = it.map { element -> element.toMap() }
        }

        style?.let {
            map["style"] = it.toMap()
        }

        return map
    }
}